#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "../umlcore/PartialElement.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class Region;
class State;
class StateMachine;
class Transition;

/// <summary>
/// Vertex
/// A Vertex is an abstraction of a node in a StateMachine graph. It can be the
/// source or destination of any number of Transitions.
/// </summary>
class UMLMODEL_EXPORT Vertex : public PartialElement {

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Methods
    /// <summary>
    /// containingStateMachine
    /// The operation containingStateMachine() returns the StateMachine in which this
    /// Vertex is defined.
    /// </summary>
    virtual shared_ptr<StateMachine> containingStateMachine() const;

    /// <summary>
    /// isContainedInState
    /// This utility operation returns true if the Vertex is contained in the State s
    /// (input argument).
    /// </summary>
    virtual bool isContainedInState(shared_ptr<State> s) const;

    /// <summary>
    /// isContainedInRegion
    /// This utility query returns true if the Vertex is contained in the Region r
    /// (input argument).
    /// </summary>
    virtual bool isContainedInRegion(shared_ptr<Region> r) const;

public: // Properties
    /// <summary>
    /// container getter
    /// The Region that contains this Vertex.
    /// </summary>
    shared_ptr<Region> container() const;

    /// <summary>
    /// container setter
    /// The Region that contains this Vertex.
    /// </summary>
    void setContainer(shared_ptr<Region> value);

    /// <summary>
    /// incomings getter
    /// Specifies the Transitions entering this Vertex.
    /// </summary>
    vector<shared_ptr<Transition>>& incomings();

    /// <summary>
    /// outgoings getter
    /// Specifies the Transitions departing from this Vertex.
    /// </summary>
    vector<shared_ptr<Transition>>& outgoings();

private: // Fields
    /// <summary>
    /// container
    /// The Region that contains this Vertex.
    /// </summary>
    shared_ptr<Region> container_;

    /// <summary>
    /// incomings
    /// Specifies the Transitions entering this Vertex.
    /// </summary>
    vector<shared_ptr<Transition>> incomings_;

    /// <summary>
    /// outgoings
    /// Specifies the Transitions departing from this Vertex.
    /// </summary>
    vector<shared_ptr<Transition>> outgoings_;

};

} // namespace uml
